package org.ffmmx.gxhotel.controller;

import org.apache.commons.lang3.StringUtils;
import org.ffmmx.common.util.TokenUtil;
import org.ffmmx.gxhotel.common.WithLog;
import org.ffmmx.gxhotel.model.PageResult;
import org.ffmmx.gxhotel.model.Result;
import org.ffmmx.gxhotel.model.hotelbs.Cguester;
import org.ffmmx.gxhotel.repository.cguester.CguesterRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/api")
public class CguesterCtrl implements WithLog{

    @Autowired
    private CguesterRepo cguesterRepo;

    @RequestMapping(method = RequestMethod.GET, path = "/cguesters")
    public Result<Cguester> list(@RequestParam String token,
                                 @RequestParam(required = false) String IDNumber,
                                 @DateTimeFormat(pattern = "yyyyMMdd") @RequestParam(required = false) Date checkInTimeStart,
                                 @DateTimeFormat(pattern = "yyyyMMdd") @RequestParam(required = false)  Date checkInTimeEnd,
                                 @DateTimeFormat(pattern = "yyyyMMdd") @RequestParam(required = false)  Date checkOutTimeStart,
                                 @DateTimeFormat(pattern = "yyyyMMdd") @RequestParam(required = false)  Date checkOutTimeEnd,
                                 @RequestParam(required = false) String stationID,
                                 @RequestParam(defaultValue = "1") Integer page,
                                 @RequestParam(defaultValue = "50") Integer limit) {
        Result<Cguester> result = null;
        try {
            if (page != null && page <= 0) {
                throw new RuntimeException("页数必须大于1");
            }
            if (limit != null && limit <= 0) {
                throw new RuntimeException("每页数必须大于0");
            }
            if ((checkInTimeStart == null || checkInTimeEnd == null) && (checkOutTimeStart == null || checkOutTimeEnd == null)) {
                throw new RuntimeException("入住时间或者退房时间至少提供一组时间范围");
            }

            Page<Cguester> cguesters = cguesterRepo.findAll(new Specification<Cguester>() {
                @Override
                public Predicate toPredicate(Root<Cguester> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                    final List<Predicate> predicates = new ArrayList<>();
                    if (StringUtils.isNotEmpty(IDNumber)) {
                        predicates.add(criteriaBuilder.equal(root.get("dj_zhengjianhaoma"), IDNumber));
                    }
                    if (checkInTimeStart != null) {
                        predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("dj_ruzhushijian"),checkInTimeStart));
                    }
                    if (checkInTimeEnd != null) {
                        predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("dj_ruzhushijian"),checkInTimeEnd));
                    }
                    if (checkOutTimeStart != null) {
                        predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("dj_tuifangshijian"),checkOutTimeStart));
                    }
                    if (checkOutTimeEnd != null) {
                        predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("dj_tuifangshijian"),checkOutTimeEnd));
                    }
                    if (StringUtils.isNotEmpty(stationID)) {
                        predicates.add(criteriaBuilder.equal(root.get("dj_lvguandaima"),stationID));
                    }
                    return criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
                }
            }, new PageRequest(page - 1, limit));
            result = new PageResult<>(cguesters);
            result.setSuccess(true);
        } catch (RuntimeException e) {
            result=new Result<Cguester>();
            result.setSuccess(false);
            result.setMsg("获取旅客入住信息发生错误:"+e.getMessage());
            if(logger().isDebugEnabled())
                result.setException(e);
            logger().error(result.getMsg(),e);
        }
        return result;
    }
}
